package util;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/**
 * JDBC 工具类
 * 使用 HikariCP 高性能连接池
 */
public class JdbcUtils {
    // 连接池对象
    private static HikariDataSource dataSource;

    static {
        try {
            // 1. 读取配置文件
            Properties props = new Properties();
            InputStream input = JdbcUtils.class.getClassLoader()
                    .getResourceAsStream("db.properties");

            if (input == null) {
                throw new RuntimeException("找不到 db.properties 配置文件");
            }

            props.load(input);

            // 2. 创建 HikariCP 连接池配置（直接使用props，不需要中间变量）
            HikariConfig config = new HikariConfig();
            config.setDriverClassName(props.getProperty("db.driver"));
            config.setJdbcUrl(props.getProperty("db.url"));
            config.setUsername(props.getProperty("db.username"));
            config.setPassword(props.getProperty("db.password"));

            // 3. 设置连接池参数
            config.setMaximumPoolSize(20);           // 最大连接数
            config.setMinimumIdle(5);                // 最小空闲连接
            config.setConnectionTimeout(30000);      // 连接超时30秒
            config.setIdleTimeout(600000);           // 空闲超时10分钟
            config.setMaxLifetime(1800000);          // 最大生命周期30分钟
            config.setPoolName("EchoNetworkPool");   // 连接池名称

            // 4. MySQL 性能优化参数
            config.addDataSourceProperty("cachePrepStmts", "true");
            config.addDataSourceProperty("prepStmtCacheSize", "250");
            config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");

            // 5. 创建连接池
            dataSource = new HikariDataSource(config);

            System.out.println("   数据库连接池初始化成功");
            System.out.println("   连接池名称: " + config.getPoolName());
            System.out.println("   最大连接数: " + config.getMaximumPoolSize());
            System.out.println("   数据库URL: " + config.getJdbcUrl());

        } catch (Exception e) {
            System.out.println("数据库连接池初始化失败");
            e.printStackTrace();
            throw new ExceptionInInitializerError("数据库连接池初始化失败: " + e.getMessage());
        }
    }

    /**
     * 从连接池获取数据库连接
     */
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    /**
     * 关闭连接资源(释放资源归还到连接池)
     */
    public static void close(Connection conn, Statement stmt, ResultSet rs) {
        try {
            if (rs != null && !rs.isClosed()) {
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        try {
            if (stmt != null && !stmt.isClosed()) {
                stmt.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        try {
            if (conn != null && !conn.isClosed()) {
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭连接和Statement
     */
    public static void close(Connection conn, Statement stmt) {
        close(conn, stmt, null);
    }

    /**
     * 只关闭连接
     */
    public static void close(Connection conn) {
        close(conn, null, null);
    }

    /**
     * 关闭连接池（应用退出时调用）
     */
    public static void closeDataSource() {
        if (dataSource != null && !dataSource.isClosed()) {
            dataSource.close();
            System.out.println("数据库连接池已关闭");
        }
    }

    /**
     * 测试数据库连接
     */
    public static void testConnection() {
        Connection conn = null;
        try {
            conn = getConnection();
            System.out.println("数据库连接测试成功！");

            // 简单的查询测试
            Statement stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT 1 as test");
            if (rs.next()) {
                System.out.println("数据库查询测试成功！");
            }
            rs.close();
            stmt.close();

        } catch (SQLException e) {
            System.out.println("数据库连接测试失败！");
            e.printStackTrace();
        } finally {
            close(conn);
        }
    }
}